<?php

namespace App\Console\Commands;

use App\Support\Mqtt\Contracts\MqttJob;
use Illuminate\Console\Command;

use React\EventLoop\Factory;
use Redis;
use Log;
use Exception;
use App\Support\Mqtt\MqttClient;

class MqttPublish extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'mqtt:publish';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'mqtt消息发布';

    /**
     * Create a new command instance.
     *
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {

        $server = config('mqtt.host');     // change if necessary
        $port = config('mqtt.port');                     // change if necessary
        $username = config('mqtt.username');                   // set your username
        $password = config('mqtt.password');                   // set your password
        $client_id = "webapp-publish"; // make sure this is unique for connecting to sever - you could use uniqid()

        $loop = Factory::create();

        $client = new MqttClient($server, $port);
        $client->setAuthentication($username,$password);
        $client->setDebug(true);
        $client->sendConnect($client_id, false, 30);  // set your client ID

        $loop->addPeriodicTimer(1, function () use (&$client, $client_id) {
            if (!$client->isConnected()) {
                $client->sendConnect($client_id, false, 30);  // set your client ID
            } else {
                $this->publishOrderStartData($client_id, $client);
            }
        });

        $loop->addPeriodicTimer(1, function () use (&$client, $client_id) {
            if (!$client->isConnected()) {
                $client->sendConnect($client_id, false, 30);  // set your client ID
            } else {
                $this->publishOrderStopData($client_id, $client);
            }
        });

        $loop->addPeriodicTimer(10, function () use (&$client) {
            $client->sendPing();
        });

        $loop->run();
    }

    /**
     * 发送订单设备停止消息
     * @param $client_id
     * @param $client
     */
    public function publishOrderStartData($client_id, &$client)
    {
        while (Redis::llen('order-device-start') > 0) {
            if (!$client->isConnected()) {
                $client->sendConnect($client_id, false, 30);  // set your client ID
            } else {
                $data = Redis::lpop('order-device-start');
                $data = unserialize($data);
                Log::debug('publish order start data', [$data]);
                $client->sendPublish('cbd/order/start', json_encode($data), 1);
            }
        }
    }

    /**
     * 发送订单设备停止消息
     * @param $client_id
     * @param $client
     */
    public function publishOrderStopData($client_id, &$client)
    {
        while (Redis::llen('order-device-stop') > 0) {
            if (!$client->isConnected()) {
                $client->sendConnect($client_id, false, 30);  // set your client ID
            } else {
                $data = Redis::lpop('order-device-stop');
                $data = unserialize($data);
                Log::debug('publish order stop data', [$data]);
                $client->sendPublish('cbd/order/stop', json_encode($data), 1);
            }
        }
    }
}
